import { Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { ArrayDataSource } from '@angular/cdk/collections';
import { CdkTree, CdkTreeNode, FlatTreeControl } from '@angular/cdk/tree';
import { NestedTreeControl } from '@angular/cdk/tree';

// flat
const TREE_DATA: ExampleFlatNode[] = [
  {
    name: 'Fruit',
    expandable: true,
    level: 0,
  }, {
    name: 'Apple',
    expandable: false,
    level: 1,
  }, {
    name: 'Banana',
    expandable: false,
    level: 1,
  }, {
    name: 'Fruit loops',
    expandable: false,
    level: 1,
  }, {
    name: 'Vegetables',
    expandable: true,
    level: 0,
  }, {
    name: 'Green',
    expandable: true,
    level: 1,
  }, {
    name: 'Broccoli',
    expandable: false,
    level: 2,
  }, {
    name: 'Brussels sprouts',
    expandable: false,
    level: 2,
  }, {
    name: 'Orange',
    expandable: true,
    level: 1,
  }, {
    name: 'Pumpkins',
    expandable: false,
    level: 2,
  }, {
    name: 'Carrots',
    expandable: false,
    level: 2,
  }
];

interface ExampleFlatNode {
  expandable: boolean;
  name: string;
  level: number;
  isExpanded?: boolean;
}

// nested
interface FoodNode {
  name: string;
  children?: FoodNode[];
}

let NESTED_TREE_DATA: FoodNode[] = [
  {
    name: 'Fruit',
    children: [
      {name: 'Apple'},
      {name: 'Banana'},
      {name: 'Fruit loops'},
    ]
  }, {
    name: 'Vegetables',
    children: [
      {
        name: 'Green',
        children: [
          {name: 'Broccoli'},
          {name: 'Brussels sprouts'},
        ]
      }, {
        name: 'Orange',
        children: [
          {name: 'Pumpkins'},
          {name: 'Carrots'},
        ]
      },
    ]
  },
];

@Component({
  selector: 'app-tree-example',
  templateUrl: './tree-example.component.html',
  styleUrls: ['./tree-example.component.sass']
})
export class TreeExampleComponent implements OnInit {

  constructor(viewContainer: ViewContainerRef) {
    this.viewContainer = viewContainer;
  }

  ngOnInit(): void {
  }

  viewContainer: ViewContainerRef;

  treeControl = new FlatTreeControl<ExampleFlatNode>(node => node.level, node => node.expandable);

  dataSource = new ArrayDataSource(TREE_DATA);

  hasChild = (_: number, node: ExampleFlatNode) => node.expandable;

  nestedTreeControl = new NestedTreeControl<FoodNode> (node => node.children);

  nestedDataSource = new ArrayDataSource(NESTED_TREE_DATA);

  nestedHasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0;

  getParentNode(node: ExampleFlatNode) {
    const nodeIndex = TREE_DATA.indexOf(node);

    for (let i = nodeIndex - 1; i >= 0; i--) {
      if (TREE_DATA[i].level === node.level - 1) {
        return TREE_DATA[i];
      }
    }

    return null;
  }

  shouldRender(node: ExampleFlatNode) {
    const parent = this.getParentNode(node);
    return !parent || parent.isExpanded;
  }

  collapseAll() {
    this.nestedTreeControl.collapseAll();
  }

  expandAll() {
    this.nestedTreeControl.dataNodes = NESTED_TREE_DATA;
    this.nestedTreeControl.expandAll();
  }

  @ViewChild('nestedTree') nestedTree: CdkTree<any>;

  insertNode(node: FoodNode) {
    // console.log(this.nestedTreeControl.getChildren(node))
    const children = this.nestedTreeControl.getChildren(node) as FoodNode[];
    children.push({
      name: 'I am new food',
      children: [],
    });
    NESTED_TREE_DATA = JSON.parse(JSON.stringify(NESTED_TREE_DATA));
    this.nestedTree.renderNodeChanges(NESTED_TREE_DATA);
    setTimeout(() => {
      this.nestedTreeControl.expand(node);
    });
    // this.nestedTree.insertNode({
    //   name: 'I am new food',
    //   children: [],
    // }, 0, this.viewContainer);
  }
}
